Hệ thống quản lý phòng khám trực tuyến bằng PHP

1 <?php
2     ########################################################################
3     
/*
4     ~~~~~~ LIST OF FUNCTIONS ~~~~~~
5         getTableList() -- returns an associative array of all tables
in this application in the format tableName=>tableCaption
6         getThumbnailSpecs($tableName, $fieldName, $view) -- returns an associative array specifying the width, height and identifier of the thumbnail file.
7         createThumbnail($img, $specs) -- $specs
is an array as returned by getThumbnailSpecs(). Returns true on success, false on failure.
8         makeSafe($
string)
9         checkPermissionVal($pvn)
10         sql($statment, $o)
11         sqlValue($statment)
12         getLoggedAdmin()
13         checkUser($username, $password)
14         logOutUser()
15         getPKFieldName($tn)
16         getCSVData($tn, $pkValue, $stripTag=
true)
17         errorMsg($msg)
18         redirect($URL, $absolute=FALSE)
19         htmlRadioGroup($name, $arrValue, $arrCaption, $selectedValue, $selClass=
"", $class="", $separator="<br>")
20         htmlSelect($name, $arrValue, $arrCaption, $selectedValue, $
class="", $selectedClass="")
21         htmlSQLSelect($name, $sql, $selectedValue, $
class="", $selectedClass="")
22         isEmail($email) -- returns $email
if valid or false otherwise.
23         notifyMemberApproval($memberID) -- send an email to member acknowledging his approval
by admin, returns false if no mail is sent
24         setupMembership() -- check
if membership tables exist or not. If not, create them.
25         thisOr($this_val, $or) --
return $this_val if it has a value, or $or if not.
26         getUploadedFile($FieldName, $MaxSize=
0, $FileTypes='csv|txt', $NoRename=false, $dir='')
27         toBytes($val)
28         convertLegacyOptions($CSVList)
29         getValueGivenCaption($query, $caption)
30         undo_magic_quotes($str)
31         time24($t) --
return time in 24h format
32         time12($t) --
return time in 12h format
33         application_url($page) --
return absolute URL of provided page
34         is_ajax() --
return true if this is an ajax request, false otherwise
35         array_trim($arr) -- recursively trim provided
value/array
36         is_allowed_username($username, $exception =
false) -- returns username if valid and unique, or false otherwise (if exception is provided and same as username, no uniqueness check is performed)
37         csrf_token($validate) -- csrf-proof a form
38         get_plugins() -- scans
for installed plugins and returns them in an array ('name', 'title', 'icon' or 'glyphicon', 'admin_path')
39         maintenance_mode($new_status =
'') -- retrieves (and optionally sets) maintenance mode status
40         html_attr($str) -- prepare $str to be placed inside an HTML attribute
41         Request($
var) -- class for providing sanitized values of given request variable (->sql, ->attr, ->html, ->url, and ->raw)
42         Notification() --
class for providing a standardized html notifications functionality
43         sendmail($mail) -- sends an email
using PHPMailer as specified in the assoc array $mail( ['to', 'name', 'subject', 'message', 'debug'] ) and returns true on success or an error message on failure
44     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
45     */

46     ########################################################################
47
48     #########################################################
49     
if(!function_exists('getTableList')){
50         function getTableList($skip_authentication =
false){
51             $arrTables = array(
52                 
'patients' => 'Patients',
53                 
'disease_symptoms' => 'Disease symptoms',
54                 
'medical_records' => 'Medical Records',
55                 
'events' => 'Appointments'
56             );
57
58             
return $arrTables;
59         }
60     }
61     ########################################################################
62     function getThumbnailSpecs($tableName, $fieldName, $view){
63         
if($tableName=='patients' && $fieldName=='image' && $view=='tv')
64             
return array('width'=>50, 'height'=>50, 'identifier'=>'_tv');
65         elseif($tableName==
'patients' && $fieldName=='image' && $view=='dv')
66             
return array('width'=>250, 'height'=>250, 'identifier'=>'_dv');
67         elseif($tableName==
'medical_records' && $fieldName=='image_1' && $view=='tv')
68             
return array('width'=>50, 'height'=>50, 'identifier'=>'_tv');
69         elseif($tableName==
'medical_records' && $fieldName=='image_1' && $view=='dv')
70             
return array('width'=>250, 'height'=>250, 'identifier'=>'_dv');
71         elseif($tableName==
'medical_records' && $fieldName=='image_2' && $view=='tv')
72             
return array('width'=>50, 'height'=>50, 'identifier'=>'_tv');
73         elseif($tableName==
'medical_records' && $fieldName=='image_2' && $view=='dv')
74             
return array('width'=>250, 'height'=>250, 'identifier'=>'_dv');
75         elseif($tableName==
'medical_records' && $fieldName=='image_3' && $view=='tv')
76             
return array('width'=>50, 'height'=>50, 'identifier'=>'_tv');
77         elseif($tableName==
'medical_records' && $fieldName=='image_3' && $view=='dv')
78             
return array('width'=>250, 'height'=>250, 'identifier'=>'_dv');
79         elseif($tableName==
'medical_records' && $fieldName=='image_4' && $view=='tv')
80             
return array('width'=>50, 'height'=>50, 'identifier'=>'_tv');
81         elseif($tableName==
'medical_records' && $fieldName=='image_4' && $view=='dv')
82             
return array('width'=>250, 'height'=>250, 'identifier'=>'_dv');
83         elseif($tableName==
'medical_records' && $fieldName=='image_5' && $view=='tv')
84             
return array('width'=>50, 'height'=>50, 'identifier'=>'_tv');
85         elseif($tableName==
'medical_records' && $fieldName=='image_5' && $view=='dv')
86             
return array('width'=>250, 'height'=>250, 'identifier'=>'_dv');
87         
return FALSE;
88     }
89     ########################################################################
90     function createThumbnail($img, $specs){
91         $w=$specs[
'width'];
92         $h=$specs[
'height'];
93         $id=$specs[
'identifier'];
94         $path=dirname($img);
95
96         
// image doesn't exist or inaccessible?
97         
if(!$size=@getimagesize($img)) return FALSE;
98
99         
// calculate thumbnail size to maintain aspect ratio
100         $ow=$size[
0]; // original image width
101         $oh=$size[
1]; // original image height
102         $twbh=$h/$oh*$ow;
// calculated thumbnail width based on given height
103         $thbw=$w/$ow*$oh;
// calculated thumbnail height based on given width
104         
if($w && $h){
105             
if($twbh>$w) $h=$thbw;
106             
if($thbw>$h) $w=$twbh;
107         }elseif($w){
108             $h=$thbw;
109         }elseif($h){
110             $w=$twbh;
111         }
else{
112             
return FALSE;
113         }
114
115         
// dir not writeable?
116         
if(!is_writable($path)) return FALSE;
117
118         
// GD lib not loaded?
119         
if(!function_exists('gd_info')) return FALSE;
120         $gd=gd_info();
121
122         
// GD lib older than 2.0?
123         preg_match(
'/\d/', $gd['GD Version'], $gdm);
124         
if($gdm[0]<2) return FALSE;
125
126         
// get file extension
127         preg_match(
'/\.[a-zA-Z]{3,4}$/U', $img, $matches);
128         $ext=strtolower($matches[
0]);
129
130         
// check if supplied image is supported and specify actions based on file type
131         
if($ext=='.gif'){
132             
if(!$gd['GIF Create Support']) return FALSE;
133             $thumbFunc=
'imagegif';
134         }elseif($ext==
'.png'){
135             
if(!$gd['PNG Support']) return FALSE;
136             $thumbFunc=
'imagepng';
137         }elseif($ext==
'.jpg' || $ext=='.jpe' || $ext=='.jpeg'){
138             
if(!$gd['JPG Support'] && !$gd['JPEG Support']) return FALSE;
139             $thumbFunc=
'imagejpeg';
140         }
else{
141             
return FALSE;
142         }
143
144         
// determine thumbnail file name
145         $ext=$matches[
0];
146         $thumb=substr($img,
0, -5).str_replace($ext, $id.$ext, substr($img, -5));
147
148         
// if the original image smaller than thumb, then just copy it to thumb
149         
if($h>$oh && $w>$ow){
150             
return (@copy($img, $thumb) ? TRUE : FALSE);
151         }
152
153         
// get image data
154         
if(!$imgData=imagecreatefromstring(implode('', file($img)))) return FALSE;
155
156         
// finally, create thumbnail
157         $thumbData=imagecreatetruecolor($w, $h);
158
159         
//preserve transparency of png and gif images
160         
if($thumbFunc=='imagepng'){
161             
if(($clr=@imagecolorallocate($thumbData, 0, 0, 0))!=-1){
162                 @imagecolortransparent($thumbData, $clr);
163                 @imagealphablending($thumbData,
false);
164                 @imagesavealpha($thumbData,
true);
165             }
166         }elseif($thumbFunc==
'imagegif'){
167             @imagealphablending($thumbData,
false);
168             $transIndex=imagecolortransparent($imgData);
169             
if($transIndex>=0){
170                 $transClr=imagecolorsforindex($imgData, $transIndex);
171                 $transIndex=imagecolorallocatealpha($thumbData, $transClr[
'red'], $transClr['green'], $transClr['blue'], 127);
172                 imagefill($thumbData,
0, 0, $transIndex);
173             }
174         }
175
176         
// resize original image into thumbnail
177         
if(!imagecopyresampled($thumbData, $imgData, 0, 0 , 0, 0, $w, $h, $ow, $oh)) return FALSE;
178         unset($imgData);
179
180         
// gif transparency
181         
if($thumbFunc=='imagegif' && $transIndex>=0){
182             imagecolortransparent($thumbData, $transIndex);
183             
for($y=0; $y<$h; ++$y)
184                 
for($x=0; $x<$w; ++$x)
185                     
if(((imagecolorat($thumbData, $x, $y)>>24) & 0x7F) >= 100) imagesetpixel($thumbData, $x, $y, $transIndex);
186             imagetruecolortopalette($thumbData,
true, 255);
187             imagesavealpha($thumbData,
false);
188         }
189
190         
if(!$thumbFunc($thumbData, $thumb)) return FALSE;
191         unset($thumbData);
192
193         
return TRUE;
194     }
195     ########################################################################
196     function makeSafe($
string, $is_gpc = true){
197         
if($is_gpc) $string = (get_magic_quotes_gpc() ? stripslashes($string) : $string);
198         
if(!db_link()){ sql("select 1+1", $eo); }
199         
return db_escape($string);
200     }
201     ########################################################################
202     function checkPermissionVal($pvn){
203         
// fn to make sure the value in the given POST variable is 0, 1, 2 or 3
204         
// if the value is invalid, it default to 0
205         $pvn=intval($_POST[$pvn]);
206         
if($pvn!=1 && $pvn!=2 && $pvn!=3){
207             
return 0;
208         }
else{
209             
return $pvn;
210         }
211     }
212     ########################################################################
213     
if(!function_exists('sql')){
214         function sql($statment, &$o){
215
216             
/*
217                 Supported options that can be passed
in $o options array (as array keys):
218                 
'silentErrors': If true, errors will be returned in $o['error'] rather than displaying them on screen and exiting.
219             */

220
221             
global $Translation;
222             
static $connected = false, $db_link;
223
224             $dbServer = config(
'dbServer');
225             $dbUsername = config(
'dbUsername');
226             $dbPassword = config(
'dbPassword');
227             $dbDatabase = config(
'dbDatabase');
228
229             ob_start();
230
231             
if(!$connected){
232                 
/****** Connect to MySQL ******/
233                 
if(!extension_loaded('mysql') && !extension_loaded('mysqli')){
234                     echo Notification::placeholder();
235                     echo Notification::show(array(
236                         
'message' => 'PHP is not configured to connect to MySQL on this machine. Please see <a href="http://www.php.net/manual/en/ref.mysql.php">this page</a> for help on how to configure MySQL.',
237                         
'class' => 'danger',
238                         
'dismiss_seconds' => 7200
239                     ));
240                     $e=ob_get_contents(); ob_end_clean();
if($o['silentErrors']){ $o['error']=$e; return FALSE; }else{ echo $e; exit; }
241                 }
242
243                 
if(!($db_link = @db_connect($dbServer, $dbUsername, $dbPassword))){
244                     echo Notification::placeholder();
245                     echo Notification::show(array(
246                         
'message' => db_error($db_link, true),
247                         
'class' => 'danger',
248                         
'dismiss_seconds' => 7200
249                     ));
250                     $e=ob_get_contents(); ob_end_clean();
if($o['silentErrors']){ $o['error']=$e; return FALSE; }else{ echo $e; exit; }
251                 }
252
253                 
/****** Select DB ********/
254                 
if(!db_select_db($dbDatabase, $db_link)){
255                     echo Notification::placeholder();
256                     echo Notification::show(array(
257                         
'message' => db_error($db_link),
258                         
'class' => 'danger',
259                         
'dismiss_seconds' => 7200
260                     ));
261                     $e=ob_get_contents(); ob_end_clean();
if($o['silentErrors']){ $o['error']=$e; return FALSE; }else{ echo $e; exit; }
262                 }
263
264                 $connected =
true;
265             }
266
267             
if(!$result = @db_query($statment, $db_link)){
268                 
if(!stristr($statment, "show columns")){
269                     
// retrieve error codes
270                     $errorNum = db_errno($db_link);
271                     $errorMsg = htmlspecialchars(db_error($db_link));
272
273                     
if(getLoggedAdmin()) $errorMsg .= "<pre>{$Translation['query:']}\n" . htmlspecialchars($statment) . "</pre><i class=\"text-right\">{$Translation['admin-only info']}</i>";
274
275                     echo Notification::placeholder();
276                     echo Notification::show(array(
277                         
'message' => $errorMsg,
278                         
'class' => 'danger',
279                         
'dismiss_seconds' => 7200
280                     ));
281                     $e = ob_get_contents(); ob_end_clean();
if($o['silentErrors']){ $o['error'] = $errorMsg; return false; }else{ echo $e; exit; }
282                 }
283             }
284
285             ob_end_clean();
286             
return $result;
287         }
288     }
289     ########################################################################
290     function sqlValue($statment){
291         
// executes a statment that retreives a single data value and returns the value retrieved
292         
if(!$res=sql($statment, $eo)){
293             
return FALSE;
294         }
295         
if(!$row=db_fetch_row($res)){
296             
return FALSE;
297         }
298         
return $row[0];
299     }
300     ########################################################################
301     function getLoggedAdmin(){
302         
// checks session variables to see whether the admin is logged or not
303         
// if not, it returns FALSE
304         
// if logged, it returns the user id
305
306         $adminConfig = config(
'adminConfig');
307
308         
if($_SESSION['adminUsername']!=''){
309             
return $_SESSION['adminUsername'];
310         }elseif($_SESSION[
'memberID']==$adminConfig['adminUsername']){
311             $_SESSION[
'adminUsername']=$_SESSION['memberID'];
312             
return $_SESSION['adminUsername'];
313         }
else{
314             
return FALSE;
315         }
316     }
317     ########################################################################
318     function checkUser($username, $password){
319         
// checks given username and password for validity
320         
// if valid, registers the username in a session and returns true
321         
// else, return FALSE and destroys session
322
323         $adminConfig = config(
'adminConfig');
324         
if($username != $adminConfig['adminUsername'] || md5($password) != $adminConfig['adminPassword']){
325             
return FALSE;
326         }
327
328         $_SESSION[
'adminUsername'] = $username;
329         $_SESSION[
'memberGroupID'] = sqlValue("select groupID from membership_users where memberID='" . makeSafe($username) ."'");
330         $_SESSION[
'memberID'] = $username;
331         
return TRUE;
332     }
333     ########################################################################
334     function logOutUser(){
335         
// destroys current session
336         $_SESSION = array();
337         
if(isset($_COOKIE[session_name()])){
338             setcookie(session_name(),
'', time()-42000, '/');
339         }
340         
if(isset($_COOKIE['online_clinic_management_system_rememberMe'])){
341             setcookie(
'online_clinic_management_system_rememberMe', '', time()-42000);
342         }
343         session_destroy();
344     }
345     ########################################################################
346     function getPKFieldName($tn){
347         
// get pk field name of given table
348
349         $stn = makeSafe($tn,
false);
350         
if(!$res = sql("show fields from `$stn`", $eo)){
351             
return false;
352         }
353
354         
while($row = db_fetch_assoc($res)){
355             
if($row['Key'] == 'PRI'){
356                 
return $row['Field'];
357             }
358         }
359
360         
return false;
361     }
362     ########################################################################
363     function getCSVData($tn, $pkValue, $stripTags=
true){
364         
// get pk field name for given table
365         
if(!$pkField=getPKFieldName($tn)){
366             
return "";
367         }
368
369         
// get a concat string to produce a csv list of field values for given table record
370         
if(!$res=sql("show fields from `$tn`", $eo)){
371             
return "";
372         }
373         
while($row=db_fetch_assoc($res)){
374             $csvFieldList.=
"`{$row['Field']}`,";
375         }
376         $csvFieldList=substr($csvFieldList,
0, -1);
377
378         $csvData=sqlValue(
"select CONCAT_WS(', ', $csvFieldList) from `$tn` where `$pkField`='" . makeSafe($pkValue, false) . "'");
379
380         
return ($stripTags ? strip_tags($csvData) : $csvData);
381     }
382     ########################################################################
383     function errorMsg($msg){
384         echo
"<div class=\"alert alert-danger\">{$msg}</div>";
385     }
386     ########################################################################
387     function redirect($URL, $absolute=FALSE){
388         $fullURL = ($absolute ? $URL : application_url($URL));
389         
if(!headers_sent()) header("Location: $fullURL");
390
391         echo
"<META HTTP-EQUIV=\"Refresh\" CONTENT=\"0;url=$fullURL\">";
392         echo
"<br><br><a href=\"$fullURL\">Click here</a> if you aren't automatically redirected.";
393         exit;
394     }
395     ########################################################################
396     function htmlRadioGroup($name, $arrValue, $arrCaption, $selectedValue, $selClass =
"text-primary", $class = "", $separator = "<br>"){
397         
if(!is_array($arrValue)) return '';
398
399         ob_start();
400         ?>
401         <div
class="radio %%CLASS%%"><label>
402             <input type=
"radio" name="%%NAME%%" id="%%ID%%" value="%%VALUE%%" %%CHECKED%%> %%LABEL%%
403         </label></div>
404         <?php
405         $template = ob_get_contents();
406         ob_end_clean();
407
408         $
out = '';
409         
for($i = 0; $i < count($arrValue); $i++){
410             $replacements = array(
411                 
'%%CLASS%%' => html_attr($arrValue[$i] == $selectedValue ? $selClass :$class),
412                 
'%%NAME%%' => html_attr($name),
413                 
'%%ID%%' => html_attr($name . $i),
414                 
'%%VALUE%%' => html_attr($arrValue[$i]),
415                 
'%%LABEL%%' => $arrCaption[$i],
416                 
'%%CHECKED%%' => ($arrValue[$i]==$selectedValue ? " checked" : "")
417             );
418             $
out .= str_replace(array_keys($replacements), array_values($replacements), $template);
419         }
420
421         
return $out;
422     }
423     ########################################################################
424     function htmlSelect($name, $arrValue, $arrCaption, $selectedValue, $
class="", $selectedClass=""){
425         
if($selectedClass==""){
426             $selectedClass=$
class;
427         }
428         
if(is_array($arrValue)){
429             $
out="<select name=\"$name\" id=\"$name\">";
430             
for($i=0; $i<count($arrValue); $i++){
431                 $
out.="<option value=\"".$arrValue[$i]."\"".($arrValue[$i]==$selectedValue ? " selected class=\"$class\"" : " class=\"$selectedClass\"").">".$arrCaption[$i]."</option>";
432             }
433             $
out.="</select>";
434         }
435         
return $out;
436     }
437     ########################################################################
438     function htmlSQLSelect($name, $sql, $selectedValue, $
class="", $selectedClass=""){
439         $arrVal[]=
'';
440         $arrCap[]=
'';
441         
if($res=sql($sql, $eo)){
442             
while($row=db_fetch_row($res)){
443                 $arrVal[]=$row[
0];
444                 $arrCap[]=$row[
1];
445             }
446             
return htmlSelect($name, $arrVal, $arrCap, $selectedValue, $class, $selectedClass);
447         }
else{
448             
return "";
449         }
450     }
451     ########################################################################
452     function bootstrapSelect($name, $arrValue, $arrCaption, $selectedValue, $
class = '', $selectedClass = ''){
453         
if($selectedClass == '') $selectedClass = $class;
454
455         $
out = "<select class=\"form-control\" name=\"{$name}\" id=\"{$name}\">";
456         
if(is_array($arrValue)){
457             
for($i = 0; $i < count($arrValue); $i++){
458                 $selected =
"class=\"{$class}\"";
459                 
if($arrValue[$i] == $selectedValue) $selected = "selected class=\"{$selectedClass}\"";
460                 $
out .= "<option value=\"{$arrValue[$i]}\" {$selected}>{$arrCaption[$i]}</option>";
461             }
462         }
463         $
out .= '</select>';
464
465         
return $out;
466     }
467     ########################################################################
468     function bootstrapSQLSelect($name, $sql, $selectedValue, $
class = '', $selectedClass = ''){
469         $arrVal[] =
'';
470         $arrCap[] =
'';
471         
if($res = sql($sql, $eo)){
472             
while($row = db_fetch_row($res)){
473                 $arrVal[] = $row[
0];
474                 $arrCap[] = $row[
1];
475             }
476             
return bootstrapSelect($name, $arrVal, $arrCap, $selectedValue, $class, $selectedClass);
477         }
478
479         
return '';
480     }
481     ########################################################################
482     function isEmail($email){
483         
if(preg_match('/^([*+!.&#$¦\'\\%\/0-9a-z^_`{}=?~:-]+)@(([0-9a-z-]+\.)+[0-9a-z]{2,45})$/i', $email)){
484             
return $email;
485         }
else{
486             
return FALSE;
487         }
488     }
489     ########################################################################
490     function notifyMemberApproval($memberID){
491         $adminConfig = config(
'adminConfig');
492         $memberID = strtolower($memberID);
493
494         $email = sqlValue(
"select email from membership_users where lcase(memberID)='{$memberID}'");
495
496         
return sendmail(array(
497             
'to' => $email,
498             
'name' => $memberID,
499             
'subject' => $adminConfig['approvalSubject'],
500             
'message' => nl2br($adminConfig['approvalMessage'])
501         ));
502     }
503     ########################################################################
504     function setupMembership(){
505         
// run once per request
506         
static $executed = false;
507         
if($executed) return;
508         $executed =
true;
509
510         
/* abort if current page is one of the following exceptions */
511         $exceptions = array(
'pageEditMember.php', 'membership_passwordReset.php', 'membership_profile.php', 'membership_signup.php', 'pageChangeMemberStatus.php', 'pageDeleteGroup.php', 'pageDeleteMember.php', 'pageEditGroup.php', 'pageEditMemberPermissions.php', 'pageRebuildFields.php', 'pageSettings.php');
512         
if(in_array(basename($_SERVER['PHP_SELF']), $exceptions)) return;
513
514         $eo = array(
'silentErrors' => true);
515
516         $adminConfig = config(
'adminConfig');
517         $today = @date(
'Y-m-d');
518
519         $membership_tables = array(
520             
'membership_groups' => "CREATE TABLE IF NOT EXISTS membership_groups (groupID int unsigned NOT NULL auto_increment, name varchar(20), description text, allowSignup tinyint, needsApproval tinyint, PRIMARY KEY (groupID)) CHARSET " . mysql_charset,
521             
'membership_users' => "CREATE TABLE IF NOT EXISTS membership_users (memberID varchar(20) NOT NULL, passMD5 varchar(40), email varchar(100), signupDate date, groupID int unsigned, isBanned tinyint, isApproved tinyint, custom1 text, custom2 text, custom3 text, custom4 text, comments text, PRIMARY KEY (memberID)) CHARSET " . mysql_charset,
522             
'membership_grouppermissions' => "CREATE TABLE IF NOT EXISTS membership_grouppermissions (permissionID int unsigned NOT NULL auto_increment, groupID int, tableName varchar(100), allowInsert tinyint, allowView tinyint NOT NULL DEFAULT '0', allowEdit tinyint NOT NULL DEFAULT '0', allowDelete tinyint NOT NULL DEFAULT '0', PRIMARY KEY (permissionID)) CHARSET " . mysql_charset,
523             
'membership_userrecords' => "CREATE TABLE IF NOT EXISTS membership_userrecords (recID bigint unsigned NOT NULL auto_increment, tableName varchar(100), pkValue varchar(255), memberID varchar(20), dateAdded bigint unsigned, dateUpdated bigint unsigned, groupID int, PRIMARY KEY (recID)) CHARSET " . mysql_charset,
524             
'membership_userpermissions' => "CREATE TABLE IF NOT EXISTS membership_userpermissions (permissionID int unsigned NOT NULL auto_increment, memberID varchar(20) NOT NULL, tableName varchar(100), allowInsert tinyint, allowView tinyint NOT NULL DEFAULT '0', allowEdit tinyint NOT NULL DEFAULT '0', allowDelete tinyint NOT NULL DEFAULT '0', PRIMARY KEY (permissionID)) CHARSET " . mysql_charset
525         );
526
527         //
get db tables
528         $tables = array();
529         $res = sql(
"show tables", $eo);
530
531         
if(!$res){
532             include_once(dirname(__FILE__) .
'/../header.php');
533             echo $eo[
'error'];
534             include_once(dirname(__FILE__) .
'/../footer.php');
535             exit;
536         }
537
538         
while($row = db_fetch_array($res)) $tables[] = $row[0];
539
540         // check
if membership tables exist or not
541         
foreach($membership_tables as $tn => $tdef){
542             
if(!in_array($tn, $tables)){
543                 sql($tdef, $eo);
544             }
545         }
546
547         // check membership_users definition
548         $membership_users = array();
549         $res = sql(
"show columns from membership_users", $eo);
550         
while($row = db_fetch_assoc($res)) $membership_users[$row['Field']] = $row;
551
552         
if(!in_array('pass_reset_key', array_keys($membership_users))) @db_query("ALTER TABLE membership_users ADD COLUMN pass_reset_key VARCHAR(100)");
553         
if(!in_array('pass_reset_expiry', array_keys($membership_users))) @db_query("ALTER TABLE membership_users ADD COLUMN pass_reset_expiry INT UNSIGNED");
554         
if(!$membership_users['groupID']['Key']) @db_query("ALTER TABLE membership_users ADD INDEX groupID (groupID)");
555
556         // create membership indices
if not existing
557         $membership_userrecords = array();
558         $res = sql(
"show keys from membership_userrecords", $eo);
559         
while($row = db_fetch_assoc($res)) $membership_userrecords[$row['Key_name']][$row['Seq_in_index']] = $row;
560
561         
if(!$membership_userrecords['pkValue'][1]) @db_query("ALTER TABLE membership_userrecords ADD INDEX pkValue (pkValue)");
562         
if(!$membership_userrecords['tableName'][1]) @db_query("ALTER TABLE membership_userrecords ADD INDEX tableName (tableName)");
563         
if(!$membership_userrecords['memberID'][1]) @db_query("ALTER TABLE membership_userrecords ADD INDEX memberID (memberID)");
564         
if(!$membership_userrecords['groupID'][1]) @db_query("ALTER TABLE membership_userrecords ADD INDEX groupID (groupID)");
565         
if(!$membership_userrecords['tableName_pkValue'][1] || !$membership_userrecords['tableName_pkValue'][2]) @db_query("ALTER IGNORE TABLE membership_userrecords ADD UNIQUE INDEX tableName_pkValue (tableName, pkValue)");
566
567         // retreive anonymous and admin groups and their permissions
568         $anon_group = $adminConfig[
'anonymousGroup'];
569         $anon_user = strtolower($adminConfig[
'anonymousMember']);
570         $admin_group =
'Admins';
571         $admin_user = strtolower($adminConfig[
'adminUsername']);
572         $groups_permissions = array();
573         $res = sql(
574             
"select g.groupID, g.name, gp.tableName, gp.allowInsert, gp.allowView, gp.allowEdit, gp.allowDelete " .
575             
"from membership_groups g left join membership_grouppermissions gp on g.groupID=gp.groupID " .
576             
"where g.name='" . makeSafe($admin_group) . "' or g.name='" . makeSafe($anon_group) . "' " .
577             
"order by g.groupID, gp.tableName", $eo
578         );
579         
while($row = db_fetch_assoc($res)) $groups_permissions[] = $row;
580
581         // check anonymous
group and user and create if necessary
582         $anon_group_id =
false;
583         
foreach($groups_permissions as $group){
584             
if($group['name'] == $anon_group){
585                 $anon_group_id = $
group['groupID'];
586                 
break;
587             }
588         }
589
590         
if(!$anon_group_id){
591             sql(
"insert into membership_groups set name='" . makeSafe($anon_group) . "', allowSignup=0, needsApproval=0, description='Anonymous group created automatically on " . @date("Y-m-d") . "'", $eo);
592             $anon_group_id = db_insert_id();
593         }
594
595         
if($anon_group_id){
596             $anon_user_db = sqlValue(
"select lcase(memberID) from membership_users where lcase(memberID)='" . makeSafe($anon_user) . "' and groupID='{$anon_group_id}'");
597             
if(!$anon_user_db || $anon_user_db != $anon_user){
598                 sql(
"delete from membership_users where groupID='{$anon_group_id}'", $eo);
599                 sql(
"insert into membership_users set memberID='" . makeSafe($anon_user) . "', signUpDate='{$today}', groupID='{$anon_group_id}', isBanned=0, isApproved=1, comments='Anonymous member created automatically on {$today}'", $eo);
600             }
601         }
602
603         // check admin
group and user and create if necessary
604         $admin_group_id =
false;
605         
foreach($groups_permissions as $group){
606             
if($group['name'] == $admin_group){
607                 $admin_group_id = $
group['groupID'];
608                 
break;
609             }
610         }
611
612         
if(!$admin_group_id){
613             sql(
"insert into membership_groups set name='" . makeSafe($admin_group) . "', allowSignup=0, needsApproval=1, description='Admin group created automatically on {$today}'", $eo);
614             $admin_group_id = db_insert_id();
615         }
616
617         
if($admin_group_id){
618             // check that admins can access all tables
619             $all_tables = getTableList(
true);
620             $tables_ok = $perms_ok = array();
621             
foreach($all_tables as $tn => $tc) $tables_ok[$tn] = $perms_ok[$tn] = false;
622
623             
foreach($groups_permissions as $group){
624                 
if($group['name'] == $admin_group){
625                     
if(isset($tables_ok[$group['tableName']])){
626                         $tables_ok[$
group['tableName']] = true;
627                         
if($group['allowInsert'] == 1 && $group['allowDelete'] == 3 && $group['allowEdit'] == 3 && $group['allowView'] == 3){
628                             $perms_ok[$
group['tableName']] = true;
629                         }
630                     }
631                 }
632             }
633
634             //
if any table has no record in Admins permissions, create one for it
635             $grant_sql = array();
636             
foreach($tables_ok as $tn => $status){
637                 
if(!$status) $grant_sql[] = "({$admin_group_id}, '{$tn}')";
638             }
639
640             
if(count($grant_sql)){
641                 sql(
"insert into membership_grouppermissions (groupID, tableName) values " . implode(',', $grant_sql), $eo);
642             }
643
644             // check admin permissions and update
if necessary
645             $perms_sql = array();
646             
foreach($perms_ok as $tn => $status){
647                 
if(!$status) $perms_sql[] = "'{$tn}'";
648             }
649
650             
if(count($perms_sql)){
651                 sql(
"update membership_grouppermissions set allowInsert=1, allowView=3, allowEdit=3, allowDelete=3 where groupID={$admin_group_id} and tableName in (" . implode(',', $perms_sql) . ")", $eo);
652             }
653
654             // check
if super admin is stored in the users table and add him if not
655             $admin_user_exists = sqlValue(
"select count(1) from membership_users where lcase(memberID)='" . makeSafe($admin_user)."' and groupID='{$admin_group_id}'");
656             
if(!$admin_user_exists){
657                 sql(
"insert into membership_users set memberID='" . makeSafe($admin_user) . "', passMD5='{$adminConfig['adminPassword']}', email='{$adminConfig['senderEmail']}', signUpDate='{$today}', groupID='{$admin_group_id}', isBanned=0, isApproved=1, comments='Admin member created automatically on {$today}'", $eo);
658             }
659         }
660     }
661
662     ########################################################################
663     function thisOr($this_val, $or =
'&nbsp;'){
664         
return ($this_val != '' ? $this_val : $or);
665     }
666     ########################################################################
667     function getUploadedFile($FieldName, $MaxSize=
0, $FileTypes='csv|txt', $NoRename=false, $dir=''){
668         $currDir=dirname(__FILE__);
669         
if(is_array($_FILES)){
670             $f = $_FILES[$FieldName];
671         }
else{
672             
return 'Your php settings don\'t allow file uploads.';
673         }
674
675         
if(!$MaxSize){
676             $MaxSize=toBytes(ini_get(
'upload_max_filesize'));
677         }
678
679         
if(!is_dir("$currDir/csv")){
680             @mkdir(
"$currDir/csv");
681         }
682
683         $dir=(is_dir($dir) && is_writable($dir) ? $dir :
"$currDir/csv/");
684
685         
if($f['error']!=4 && $f['name']!=''){
686             
if($f['size']>$MaxSize || $f['error']){
687                 
return 'File size exceeds maximum allowed of '.intval($MaxSize / 1024).'KB';
688             }
689             
if(!preg_match('/\.('.$FileTypes.')$/i', $f['name'], $ft)){
690                 
return 'File type not allowed. Only these file types are allowed: '.str_replace('|', ', ', $FileTypes);
691             }
692
693             
if($NoRename){
694                 $n = str_replace(
' ', '_', $f['name']);
695             }
else{
696                 $n = microtime();
697                 $n = str_replace(
' ', '_', $n);
698                 $n = str_replace(
'0.', '', $n);
699                 $n .= $ft[
0];
700             }
701
702             
if(!@move_uploaded_file($f['tmp_name'], $dir . $n)){
703                 
return 'Couldn\'t save the uploaded file. Try chmoding the upload folder "'.$dir.'" to 777.';
704             }
else{
705                 @chmod($dir.$n,
0666);
706                 
return $dir.$n;
707             }
708         }
709         
return 'An error occured while uploading the file. Please try again.';
710     }
711     ########################################################################
712     function toBytes($val){
713         $val = trim($val);
714         $last = strtolower($val{strlen($val)-
1});
715         
switch($last){
716              // The
'G' modifier is available since PHP 5.1.0
717              
case 'g':
718                     $val *=
1024;
719              
case 'm':
720                     $val *=
1024;
721              
case 'k':
722                     $val *=
1024;
723         }
724
725         
return $val;
726     }
727     ########################################################################
728     function convertLegacyOptions($CSVList){
729         $CSVList=str_replace(
';;;', ';||', $CSVList);
730         $CSVList=str_replace(
';;', '||', $CSVList);
731         
return $CSVList;
732     }
733     ########################################################################
734     function getValueGivenCaption($query, $caption){
735         
if(!preg_match('/select\s+(.*?)\s*,\s*(.*?)\s+from\s+(.*?)\s+order by.*/i', $query, $m)){
736             
if(!preg_match('/select\s+(.*?)\s*,\s*(.*?)\s+from\s+(.*)/i', $query, $m)){
737                 
return '';
738             }
739         }
740
741         //
get where clause if present
742         
if(preg_match('/\s+from\s+(.*?)\s+where\s+(.*?)\s+order by.*/i', $query, $mw)){
743             $
where="where ($mw[2]) AND";
744             $m[
3]=$mw[1];
745         }
else{
746             $
where='where';
747         }
748
749         $caption=makeSafe($caption);
750         
return sqlValue("SELECT $m[1] FROM $m[3] $where $m[2]='$caption'");
751     }
752     ########################################################################
753     function undo_magic_quotes($str){
754         
return (get_magic_quotes_gpc() ? stripslashes($str) : $str);
755     }
756     ########################################################################
757     function time24($t =
false){
758         
if($t === false) $t = date('Y-m-d H:i:s');
759         
return date('H:i:s', strtotime($t));
760     }
761     ########################################################################
762     function time12($t =
false){
763         
if($t === false) $t = date('Y-m-d H:i:s');
764         
return date('h:i:s A', strtotime($t));
765     }
766     ########################################################################
767     function application_url($page =
'', $s = false){
768         
if($s === false) $s = $_SERVER;
769         $ssl = (!empty($s[
'HTTPS']) && $s['HTTPS'] == 'on');
770         $http = ($ssl ?
'https:' : 'http:');
771         $port = $s[
'SERVER_PORT'];
772         $port = ((!$ssl && $port ==
'80') || ($ssl && $port == '443')) ? '' : ':' . $port;
773         $host = (isset($s[
'HTTP_HOST']) ? $s['HTTP_HOST'] : $s['SERVER_NAME'] . $port);
774         $uri = dirname($s[
'SCRIPT_NAME']);
775
776         
/* app folder name (without the ending /admin part) */
777         $app_folder_is_admin =
false;
778         $app_folder = substr(dirname(__FILE__),
0, -6);
779         
if(substr($app_folder, -6, 6) == '/admin' || substr($app_folder, -6, 6) == '\\admin')
780             $app_folder_is_admin =
true;
781
782         
if(substr($uri, -12, 12) == '/admin/admin') $uri = substr($uri, 0, -6);
783         elseif(substr($uri, -
6, 6) == '/admin' && !$app_folder_is_admin) $uri = substr($uri, 0, -6);
784         elseif($uri ==
'/' || $uri == '\\') $uri = '';
785
786         
return "{$http}//{$host}{$uri}/{$page}";
787     }
788     ########################################################################
789     function is_ajax(){
790         
return (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest');
791     }
792     ########################################################################
793     function array_trim($arr){
794         
if(!is_array($arr)) return trim($arr);
795         
return array_map('array_trim', $arr);
796     }
797     ########################################################################
798     function is_allowed_username($username, $exception =
false){
799         $username = trim(strtolower($username));
800         
if(!preg_match('/^[a-z0-9][a-z0-9 _.@]{3,19}$/', $username) || preg_match('/(@@| |\.\.|___)/', $username)) return false;
801
802         
if($username == $exception) return $username;
803
804         
if(sqlValue("select count(1) from membership_users where lcase(memberID)='{$username}'")) return false;
805         
return $username;
806     }
807     ########################################################################
808     
/*
809         
if called without parameters, looks for a non-expired token in the user's session (or creates one if
810         none found) and returns html code to insert
into the form to be protected.
811
812         
if set to true, validates token sent in $_REQUEST against that stored in the session
813         and returns
true if valid or false if invalid, absent or expired.
814
815         usage:
816             
1. in a new form that needs csrf proofing: echo csrf_token();
817                >> 
in case of ajax requests and similar, retrieve token directly
818                   
by calling csrf_token(false, true);
819             
2. when validating a submitted form: if(!csrf_token(true)){ reject_submission_somehow(); }
820     */

821     function csrf_token($validate =
false, $token_only = false){
822         $token_age =
60 * 60;
823         
/* retrieve token from session */
824         $csrf_token = (isset($_SESSION[
'csrf_token']) ? $_SESSION['csrf_token'] : false);
825         $csrf_token_expiry = (isset($_SESSION[
'csrf_token_expiry']) ? $_SESSION['csrf_token_expiry'] : false);
826
827         
if(!$validate){
828             
/* create a new token if necessary */
829             
if($csrf_token_expiry < time() || !$csrf_token){
830                 $csrf_token = md5(uniqid(rand(),
true));
831                 $csrf_token_expiry = time() + $token_age;
832                 $_SESSION[
'csrf_token'] = $csrf_token;
833                 $_SESSION[
'csrf_token_expiry'] = $csrf_token_expiry;
834             }
835
836             
if($token_only) return $csrf_token;
837             
return '<input type="hidden" id="csrf_token" name="csrf_token" value="' . $csrf_token . '">';
838         }
839
840         
/* validate submitted token */
841         $user_token = (isset($_REQUEST[
'csrf_token']) ? $_REQUEST['csrf_token'] : false);
842         
if($csrf_token_expiry < time() || !$user_token || $user_token != $csrf_token){
843             
return false;
844         }
845
846         
return true;
847     }
848     ########################################################################
849     function get_plugins(){
850         $plugins = array();
851         $plugins_path = dirname(__FILE__) .
'/../plugins/';
852
853         
if(!is_dir($plugins_path)) return $plugins;
854
855         $pd = dir($plugins_path);
856         
while(false !== ($plugin = $pd->read())){
857             
if(!is_dir($plugins_path . $plugin) || in_array($plugin, array('projects', 'plugins-resources', '.', '..'))) continue;
858
859             $info_file =
"{$plugins_path}{$plugin}/plugin-info.json";
860             
if(!is_file($info_file)) continue;
861
862             $plugins[] = json_decode(file_get_contents($info_file),
true);
863             $plugins[count($plugins) -
1]['admin_path'] = "../plugins/{$plugin}";
864         }
865         $pd->close();
866
867         
return $plugins;
868     }
869     ########################################################################
870     function maintenance_mode($new_status =
''){
871         $maintenance_file = dirname(__FILE__) .
'/.maintenance';
872
873         
if($new_status === true){
874             
/* turn on maintenance mode */
875             @touch($maintenance_file);
876         }elseif($new_status ===
false){
877             
/* turn off maintenance mode */
878             @unlink($maintenance_file);
879         }
880
881         
/* return current maintenance mode status */
882         
return is_file($maintenance_file);
883     }
884     ########################################################################
885     function handle_maintenance($echo =
false){
886         
if(!maintenance_mode()) return;
887
888         
global $Translation;
889         $adminConfig = config(
'adminConfig');
890
891         $admin = getLoggedAdmin();
892         
if($admin){
893             
return ($echo ? '<div class="alert alert-danger" style="margin: 5em auto -5em;"><b>' . $Translation['maintenance mode admin notification'] . '</b></div>' : '');
894         }
895
896         
if(!$echo) exit;
897
898         exit(
'<div class="alert alert-danger" style="margin-top: 5em; font-size: 2em;"><i class="glyphicon glyphicon-exclamation-sign"></i> ' . $adminConfig['maintenance_mode_message'] . '</div>');
899     }
900     #########################################################
901     function html_attr($str){
902         
return htmlspecialchars($str, ENT_QUOTES, datalist_db_encoding);
903     }
904     #########################################################
905     
class Request{
906         
var $sql, $url, $attr, $html, $raw;
907
908         function __construct($
var, $filter = false){
909             $
this->Request($var, $filter);
910         }
911
912         function Request($
var, $filter = false){
913             $
unsafe = (isset($_REQUEST[$var]) ? $_REQUEST[$var] : '');
914             
if(get_magic_quotes_gpc()) $unsafe = stripslashes($unsafe);
915
916             
if($filter){
917                 $
unsafe = call_user_func($filter, $unsafe);
918             }
919
920             $
this->sql = makeSafe($unsafe, false);
921             $
this->url = urlencode($unsafe);
922             $
this->attr = html_attr($unsafe);
923             $
this->html = html_attr($unsafe);
924             $
this->raw = $unsafe;
925         }
926     }
927     #########################################################
928     
class Notification{
929         
/*
930             Usage:
931             *
in the main document, initiate notifications support using this PHP code:
932                 echo Notification::placeholder();
933
934             * whenever you want to show a notifcation, use
this PHP code:
935                 echo Notification::show(array(
936                     
'message' => 'Notification text to display',
937                     
'class' => 'danger', // or other bootstrap state cues, 'default' if not provided
938                     
'dismiss_seconds' => 5, // optional auto-dismiss after x seconds
939                     
'dismiss_days' => 7, // optional dismiss for x days if closed by user -- must provide an id
940                     
'id' => 'xyz' // optional string to identify the notification -- must use for 'dismiss_days' to work
941                 ));
942         */

943         
protected static $placeholder_id; /* to force a single notifcation placeholder */
944
945         
protected function __construct(){} /* to prevent initialization */
946
947         
public static function placeholder(){
948             
if(self::$placeholder_id) return ''; // output placeholder code only once
949
950             self::$placeholder_id =
'notifcation-placeholder-' . rand(10000000, 99999999);
951
952             ob_start();
953             ?>
954
955             <div
class="notifcation-placeholder" id="<?php echo self::$placeholder_id; ?>"></div>
956             <script>
957                 $j(function(){
958                     
if(window.show_notification != undefined) return;
959
960                     window.show_notification = function(options){
961                         
/* wait till all dependencies ready */
962                         
if(window.notifications_ready == undefined){
963                             
var op = options;
964                             setTimeout(function(){ show_notification(op); },
20);
965                             
return;
966                         }
967
968                         
var dismiss_class = '';
969                         
var dismiss_icon = '';
970                         
var cookie_name = 'hide_notification_' + options.id;
971                         
var notif_id = 'notifcation-' + Math.ceil(Math.random() * 1000000);
972
973                         
/* apply provided notficiation id if unique in page */
974                         
if(options.id != undefined){
975                             
if(!$j('#' + options.id).length) notif_id = options.id;
976                         }
977
978                         
/* notifcation should be hidden? */
979                         
if(Cookies.get(cookie_name) != undefined) return;
980
981                         
/* notification should be dismissable? */
982                         
if(options.dismiss_seconds > 0 || options.dismiss_days > 0){
983                             dismiss_class =
' alert-dismissible';
984                             dismiss_icon =
'<button type="button" class="close" data-dismiss="alert">&times;</button>';
985                         }
986
987                         
/* remove old dismissed notficiations */
988                         $j(
'.alert-dismissible.invisible').remove();
989
990                         
/* append notification to notifications container */
991                         $j(
992                             
'<div class="alert alert-' + options['class'] + dismiss_class + '" id="' + notif_id + '">' +
993                                 dismiss_icon +
994                                 options.message +
995                             
'</div>'
996                         ).appendTo(
'#<?php echo self::$placeholder_id; ?>');
997
998                         
var this_notif = $j('#' + notif_id);
999
1000                         
/* dismiss after x seconds if requested */
1001                         
if(options.dismiss_seconds > 0){
1002                             setTimeout(function(){ this_notif.addClass(
'invisible'); }, options.dismiss_seconds * 1000);
1003                         }
1004
1005                         
/* dismiss for x days if requested and user dismisses it */
1006                         
if(options.dismiss_days > 0){
1007                             
var ex_days = options.dismiss_days;
1008                             this_notif.
on('closed.bs.alert', function(){
1009                                 
/* set a cookie not to show this alert for ex_days */
1010                                 Cookies.
set(cookie_name, '1', { expires: ex_days });
1011                             });
1012                         }
1013                     }
1014
1015                     
/* cookies library already loaded? */
1016                     
if(undefined != window.Cookies){
1017                         window.notifications_ready =
true;
1018                         
return;
1019                     }
1020
1021                     
/* load cookies library */
1022                     $j.ajax({
1023                         url:
'<?php echo PREPEND_PATH; ?>resources/jscookie/js.cookie.js',
1024                         dataType:
'script',
1025                         cache:
true,
1026                         success: function(){ window.notifications_ready =
true; }
1027                     });
1028                 })
1029             </script>
1030
1031             <?php
1032             $html = ob_get_contents();
1033             ob_end_clean();
1034
1035             
return $html;
1036         }
1037
1038         
protected static function default_options(&$options){
1039             
if(!isset($options['message'])) $options['message'] = 'Notification::show() called without a message!';
1040
1041             
if(!isset($options['class'])) $options['class'] = 'default';
1042
1043             
if(!isset($options['dismiss_seconds']) || isset($options['dismiss_days'])) $options['dismiss_seconds'] = 0;
1044
1045             
if(!isset($options['dismiss_days'])) $options['dismiss_days'] = 0;
1046             
if(!isset($options['id'])){
1047                 $options[
'id'] = 0;
1048                 $options[
'dismiss_days'] = 0;
1049             }
1050         }
1051
1052         
/**
1053          * @brief Notification::show($options) displays a notification
1054          *
1055          * @param $options assoc array
1056          *
1057          * @
return html code for displaying the notifcation
1058          */

1059         
public static function show($options = array()){
1060             self::default_options($options);
1061
1062             ob_start();
1063             ?>
1064             <script>
1065                 $j(function(){
1066                     show_notification(<?php echo json_encode($options); ?>);
1067                 })
1068             </script>
1069             <?php
1070             $html = ob_get_contents();
1071             ob_end_clean();
1072
1073             
return $html;
1074         }
1075     }
1076     #########################################################
1077     function sendmail($mail){
1078         
if(!isset($mail['to'])) return 'No recipient defined';
1079         
if(!isEmail($mail['to'])) return 'Invalid recipient email';
1080
1081         $mail[
'subject'] = isset($mail['subject']) ? $mail['subject'] : '';
1082         $mail[
'message'] = isset($mail['message']) ? $mail['message'] : '';
1083         $mail[
'name'] = isset($mail['name']) ? $mail['name'] : '';
1084         $mail[
'debug'] = isset($mail['debug']) ? min(4, max(0, intval($mail['debug']))) : 0;
1085
1086         $cfg = config(
'adminConfig');
1087         $smtp = ($cfg[
'mail_function'] == 'smtp');
1088
1089         
if(!class_exists('PHPMailer')){
1090             $curr_dir = dirname(__FILE__);
1091             include(
"{$curr_dir}/../resources/PHPMailer/class.phpmailer.php");
1092             
if($smtp) include("{$curr_dir}/../resources/PHPMailer/class.smtp.php");
1093         }
1094
1095         $pm =
new PHPMailer;
1096         $pm->CharSet = datalist_db_encoding;
1097
1098         
if($smtp){
1099             $pm->isSMTP();
1100             $pm->SMTPDebug = $mail[
'debug'];
1101             $pm->Debugoutput =
'html';
1102             $pm->Host = $cfg[
'smtp_server'];
1103             $pm->Port = $cfg[
'smtp_port'];
1104             $pm->SMTPAuth =
true;
1105             $pm->SMTPSecure = $cfg[
'smtp_encryption'];
1106             $pm->Username = $cfg[
'smtp_user'];
1107             $pm->Password = $cfg[
'smtp_pass'];
1108         }
1109
1110         $pm->setFrom($cfg[
'senderEmail'], $cfg['senderName']);
1111         $pm->addAddress($mail[
'to'], $mail['name']);
1112         $pm->Subject = $mail[
'subject'];
1113
1114         
/* if message already contains html tags, don't apply nl2br */
1115         
if($mail['message'] == strip_tags($mail['message']))
1116             $mail[
'message'] = nl2br($mail['message']);
1117
1118         $pm->msgHTML($mail[
'message'], realpath("{$curr_dir}/.."));
1119
1120         
/* if sendmail_handler(&$pm) is defined (in hooks/__global.php) */
1121         
if(function_exists('sendmail_handler')) sendmail_handler($pm);
1122
1123         
if(!$pm->send()) return $pm->ErrorInfo;
1124
1125         
return true;
1126     }


Gõ tìm kiếm nhanh...